#include <libpub.h>
#include <config.h>

#define TEST_SAMPLERATE 44100
#if 0
unsigned int testSameple[] = {
    0x00000000,    0x10B50000,    0x21200000,   0x30FB0000,
    0x3FFF0000,    0x4DEB0000,    0x5A820000,   0x658C0000,
    0x6ED90000,    0x76410000,    0x7BA30000,   0x7EE70000,
    0x7FFF0000,    0x7EE70000,    0x7BA30000,   0x76410000,
    0x6ED90000,    0x658C0000,    0x5A820000,   0x4DEB0000,
    0x3FFF0000,    0x30FB0000,    0x21200000,   0x10B50000,
    0x00000000,    0xEF4B0000,    0xDEE00000,   0xCF050000,
    0xC0000000,    0xB2150000,    0xA57E0000,   0x9A740000,
    0x91270000,    0x89BF0000,    0x845D0000,   0x81190000,
    0x80000000,    0x81190000,    0x845D0000,   0x89BF0000,
    0x91270000,    0x9A740000,    0xA57E0000,   0xB2150000,
    0xC0000000,    0xCF050000,    0xDEE00000,   0xEF4B0000,
};
#else
#include "audiotest.h"
#endif

extern "C"{
int Audio_Init(int param);

int Audio_PrepareReplay(int rate);
int Audio_Play(void *pBuffer, int len);
int Audio_SetOutPath(int path);

int Audio_PrepareRecord(int rate);
int Audio_Record(void *pBuffer, int len);
int Audio_SetInPath(int path);
}

static void PlayProcess(int source)
{
    Audio_Init(1);
    Audio_PrepareReplay(TEST_SAMPLERATE);
    Audio_SetOutPath(source);
    Audio_Play((void *)testSameple, sizeof(testSameple));
}

int Do_Codec_PlayBySpeaker(char * param)
{
    PlayProcess(0);
    return 0;
}

int Do_Codec_PlayByHeadset(char * param)
{
    PlayProcess(1);

    return 0;
}

int Do_Codec_loopByReceive(char * param)
{

    return 0;
}

static void RecordAndPlayProcess(int source)
{
    unsigned short *testBuffer = (unsigned short *)TEMP_BUFFER;

    printf("Now recording by MAIN microphone.\n");
    Audio_Init(1);
    Audio_PrepareRecord(TEST_SAMPLERATE);
    Audio_SetInPath(source);
    Audio_Record((void *)testBuffer, 4096 * 100);

    printf("Finish recording. Now playing...\n");

    Audio_PrepareReplay(TEST_SAMPLERATE);
    Audio_SetOutPath(source);
    Audio_Play((void *)testBuffer, 4096 * 100);
}

int Do_Codec_RecordByMainMIC(char * param)
{
    RecordAndPlayProcess(0);
    return 0;
}

int Do_Codec_RecordByHeadsetMIC(char * param)
{
    RecordAndPlayProcess(1);
    return 0;
}

int Do_Codec_pcmTxRx(char * param)
{
//    PcmRxTxTest(param);
    return 0;
}
tCommandTbl Do_TestCodecCmdTbl[] = {
    {Do_Codec_PlayBySpeaker,         "PlayBySpeaker",      ""},
    {Do_Codec_PlayByHeadset,     "PlayByHeadset",    ""},
    {Do_Codec_RecordByMainMIC,    "RecordByMainMIC",  ""},
    {Do_Codec_RecordByHeadsetMIC,    "RecordByHeadsetMIC",  ""},
    {Do_Codec_loopByReceive,   "loopByReceive", ""},
    {Do_Codec_pcmTxRx,   "pcmRxTxTest", ""},
    CMD_NULL,               //DO NOT REMOVE
};

void AudioClose();

const unsigned short c_speakerVolumeTable[] = {
    //0,  1,  2,  3,  4,  5,  6,  7, 8, 9, 10, 11, 12, 13, 14, 15     input
     31, 18, 15, 12, 10,  8,  7,  6, 5, 4,  3,  3,  2,  2,  1,  0  // ouput
    };

void AudioClose()
{
}

//==================
int _Do_Test_Audio(char *param)
{
#if 1
TOUT(1, 1, printf("_Do_Test_Audio (\"%s\")\n", param));

 if (*param) {
//     DisplayBlack();
     Bo_ExeCommand(Do_TestCodecCmdTbl, param);
 }
 else {
     static tMenuTbl Do_TestCodecMenuTbl[] = {
         {'0', "Play PCM wave by speaker",     "PlayBySpeaker"},
         {'1', "Play PCM wave by headset",  "PlayByHeadset"},
         {'2', "Record PCM wave by main microphone", "RecordByMainMIC"},
         {'3', "Record PCM wave by headset microphone", "RecordByHeadsetMIC"},
//         {'4', "Test CODEC loopByReceive",  "loopByReceive"},
//         {'5', "pcmPlay->RecordByMainMIC->pcmPlayback","pcmRxTxTest"},
         {    0, MENU_NULL},         //DO NOT REMOVE
     };
     Bo_ShowMenu(Do_TestCodecMenuTbl, Do_TestCodecCmdTbl, 1);
 }

#else
     TOUT(1, 1, printf("\n_Do_Test_Audio(%s):\n", param));
     char *func = NULL;
     if(*param){//test audio
        param = Bo_ParseString(param, &func);
        if(0 == Bo_MatchString(func , "play")) {//test audio play
            //Do test audio play code
            printf("\ntest audio play...\n");
            AudioTest(c_speakerVolumeTable[14]);//default volume level is highest
        }
        else if(0 <= Bo_MatchString("volume", func)){//test audio volume
            if(*param) {
                param = Bo_ParseString(param, &func);
                if(0 == Bo_MatchString(func, "auto")){//test audio volume auto
                    printf("\nvolume auto\n");
                    for(int i = 0; i <= 15; i++){
                        printf("\nPlay at volume level %2d ...", i);
                        AudioTest(c_speakerVolumeTable[i]);//TODO: Choice new audio file
                    }
                }
                else {//test audio volume {val}
                    int volume = Bo_ConvertString(func);
                    printf("\nPlay at volume = %d ...", volume);
                    if (volume <= 0 || volume > 31) {
                            printf("Invalid volume value\n");
                            return -1;
                    }
                    else {
                        AudioTest(volume);//TODO: Choice new audio file
                    }
                }
            }
        }
     }

    AudioClose();
#endif

    return 0;
}
